﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using System.Windows.Media.Imaging;

namespace TorchView.Imaging
{
  public sealed class DDSLoader : IDisposable
  {
    private GraphicsDevice _Device;

    public DDSLoader()
    {
      // Create the graphics device
      _Device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.NullReference, IntPtr.Zero, new PresentationParameters());
    }

    ~DDSLoader()
    {
      Dispose(false);
    }

    public ImageSource Load(string filename)
    {
      return Load(File.OpenRead(filename));
    }

    public BitmapSource Load(Stream stream)
    {
      // Setup the texture creation parameters
      var textureCreationParameters = new TextureCreationParameters()
      {
        Width = -1,
        Height = -1,
        Depth = 1,
        TextureUsage = TextureUsage.None,
        Format = SurfaceFormat.Color,
        Filter = FilterOptions.None,
        MipFilter = FilterOptions.None,
        MipLevels = 1
      };

      // Load the texture
      using (var texture = Texture2D.FromFile(_Device, stream, textureCreationParameters))
      {
        // Get the pixel data
        var pixelColors = new Microsoft.Xna.Framework.Graphics.Color[texture.Width * texture.Height];
        texture.GetData(pixelColors);

        // Copy the pixel colors into a byte array
        var bytesPerPixel = 4;
        var stride = texture.Width * bytesPerPixel;

        var pixelData = new byte[pixelColors.Length * bytesPerPixel];
        for (var i = 0; i < pixelColors.Length; i++)
        {
          var pixel = pixelColors[i];
          byte alpha = pixel.A;
          var alphaPercentage = alpha / byte.MaxValue;
          pixelData[i * bytesPerPixel + 0] = (byte)(pixel.B * alphaPercentage);
          pixelData[i * bytesPerPixel + 1] = (byte)(pixel.G * alphaPercentage);
          pixelData[i * bytesPerPixel + 2] = (byte)(pixel.R * alphaPercentage);
          pixelData[i * bytesPerPixel + 3] = alpha;
        }

        // Create a bitmap source
        return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Pbgra32, null, pixelData, stride);
      }
    }

    #region IDisposable Members

    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
      if (_Device != null)
        _Device.Dispose();
      _Device = null;
    }

    #endregion
  }
}
